package com.sam.shiro;

import com.alibaba.druid.util.StringUtils;
import com.sam.domain.entity.SysPerms;
import com.sam.domain.entity.SysUser;
import com.sam.domain.entity.SysUserRole;
import com.sam.service.ISysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 自定义Realm完成具体的认证和授权操作
 *
 * @author sam
 * @since 2025-01-08 16:24
 */
public class MyRealm extends AuthorizingRealm {

    @Autowired
    protected ISysUserService sysUserService;

    /**
     * 自定义用户授权方法
     * @param principals the primary identifying principals of the AuthorizationInfo that should be retrieved.
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("执行了授权");
        //从Shiro中获取用户名
        Object username = principals.getPrimaryPrincipal();
        //创建一个SimpleAuthorizationInfo类的对象，利用这个对象需要设置当前用户的权限信息
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();

        //获取用户信息
        SysUser sysUser = sysUserService.selectUserByName(username.toString());
        if (sysUser == null) {
            throw  new UnknownAccountException("账号不存在");
        }


        //创建角色信息的集合
        //Set<String> roles=new HashSet<String>();
        //这里应该根据账号到数据库中获取用户的所对应的所有角色信息并初始化到roles集合中
        //if("admin".equals(username)) {
            //roles.add("admin");
           // roles.add("user");
        //} else if ("zhangsan".equals(username)){
            //roles.add("user");
        //}
        List<SysUserRole> roleList = sysUserService.selectUserRoleByUserId(sysUser.getUserId());
//        if (roleList.size() == 0) {
//            throw  new UnknownAccountException("用户角色不存在");
//        }
        Set<String> roles=new HashSet<String>();
        for (SysUserRole sysUserRole : roleList) {
            roles.add(sysUserRole.getRoleKey());
        }
        Set<String>psermission=new HashSet<String>();
        List<SysPerms> permsList = sysUserService.selectRolePermsByUserId(sysUser.getUserId());
//        if (permsList.size() == 0) {
//            throw  new UnknownAccountException("用户权限不存在");
//        }
        for (SysPerms sysPerms : permsList) {
            psermission.add(sysPerms.getPerms());
        }
//        if("admin".equals(username)){
//            psermission.add("admin:update");
//            psermission.add("admin:add");
//        }
        //设置角色信息
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(psermission);
        return simpleAuthorizationInfo;
    }

    /**
     * 自定义认证方法
     * @param authenticationToken the authentication token submitted to the system
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //log.info("正在进行用户登录认证->doGetAuthenticationInfo()");
        //将AuthenticationToken强转成UsernamePasswordToken 这样获取账号和密码更加的方便
        UsernamePasswordToken token= (UsernamePasswordToken)authenticationToken;
        //获取用户在浏览器中输入的账号
        //String username = token.getUsername();
        //认证账号,正常情况我们需要这里从数据库中获取账号的信息，以及其他关键数据，例如账号是否被冻结等等
        if (StringUtils.isEmpty(token.getUsername())) {
            throw  new UnknownAccountException("用户名为空");
        }
        SysUser sysUser = sysUserService.selectUserByName(token.getUsername());
        if (sysUser == null) {
            throw  new UnknownAccountException("账号不存在");
        }
//        String dbusername=username;
//        if(!"admin".equals(dbusername)&&!"zhangsan".equals(dbusername)){//判断用户账号是否正确
//            throw  new UnknownAccountException("账号错误");
//        }
//        if("zhangsan".equals(username)){
//            throw  new LockedAccountException("账号被锁定");
//        }
        //定义一个密码这个密码应该来自数据库中
        //String dbpassword="123456";
        //认证密码是否正确
        return new SimpleAuthenticationInfo(sysUser.getUserName(),sysUser.getPassword(),getName());
    }


}
